#include "warray/warray_round.h"
#include "test.h"

#include <iostream>

#include "helper.h"

typedef boost::mpl::list< float,double > test_scalar_types;

BOOST_AUTO_TEST_CASE_TEMPLATE( array_floor, T, test_scalar_types )
{
	warp::arraynd<T,1> x(warp::extents[16]);
	fill_nonzero(x);
	
	warp::arraynd<T,1> z(x.dims()); 
	warp::floor(x,z);
	BOOST_CHECK_EQUAL(x.dims(),z.dims());
	BOOST_CHECK( (array_equal(x,z,std::ptr_fun<T,T>(std::floor))) );
	
	z = warp::floor(x);
	BOOST_CHECK_EQUAL(x.dims(),z.dims());
	BOOST_CHECK( (array_equal(x,z,std::ptr_fun<T,T>(std::floor))) );
	
	z = x.copy();
	warp::floor(z,z);
	BOOST_CHECK_EQUAL(x.dims(),z.dims());
	BOOST_CHECK( (array_equal(x,z,std::ptr_fun<T,T>(std::floor))) );
}

BOOST_AUTO_TEST_CASE_TEMPLATE( array_ceil, T, test_scalar_types )
{
	warp::arraynd<T,1> x(warp::extents[16]);
	fill_nonzero(x);
	
	warp::arraynd<T,1> z(x.dims()); 
	warp::ceil(x,z);
	BOOST_CHECK_EQUAL(x.dims(),z.dims());
	BOOST_CHECK( (array_equal(x,z,std::ptr_fun<T,T>(std::ceil))) );
	
	z = warp::ceil(x);
	BOOST_CHECK_EQUAL(x.dims(),z.dims());
	BOOST_CHECK( (array_equal(x,z,std::ptr_fun<T,T>(std::ceil))) );
	
	z = x.copy();
	warp::ceil(z,z);
	BOOST_CHECK_EQUAL(x.dims(),z.dims());
	BOOST_CHECK( (array_equal(x,z,std::ptr_fun<T,T>(std::ceil))) );
}

BOOST_AUTO_TEST_CASE_TEMPLATE( array_abs, T, test_scalar_types )
{
	warp::arraynd<T,1> x(warp::extents[16]);
	fill_nonzero(x);
	
	warp::arraynd<T,1> z(x.dims()); 
	warp::abs(x,z);
	BOOST_CHECK_EQUAL(x.dims(),z.dims());
	BOOST_CHECK( (array_equal(x,z,warp::detail::choose_abs<T>())) );
	
	z = warp::abs(x);
	BOOST_CHECK_EQUAL(x.dims(),z.dims());
	BOOST_CHECK( (array_equal(x,z,warp::detail::choose_abs<T>())) );
	
	z = x.copy();
	warp::abs(z,z);
	BOOST_CHECK_EQUAL(x.dims(),z.dims());
	BOOST_CHECK( (array_equal(x,z,warp::detail::choose_abs<T>())) );
	
	warp::arraynd<std::complex<T>,1> y(warp::extents[16]);
	fill_nonzero(y);
	
	warp::abs(y,z);
	BOOST_CHECK_EQUAL(y.dims(),z.dims());
	BOOST_CHECK( (array_equal(y,z,warp::detail::choose_abs<std::complex<T> >())) );
	
	z = warp::abs(y);
	BOOST_CHECK_EQUAL(y.dims(),z.dims());
	BOOST_CHECK( (array_equal(y,z,warp::detail::choose_abs<std::complex<T> >())) );
}
